/*
 *
 *  Copyright (C) THL A29 Limited, a Tencent company. All rights reserved.
 *  SPDX-License-Identifier: Apache-2.0
 *
 */
import { CertOrg } from '../certificates/interface';
import { PageQuery, TableFilterField } from '../../interface';
import { AuthRoleMap } from '../../../routes/chains/chain-auth';

export type ChainModes = 'permissionedWithCert' | 'public';
export interface Chain {
  Id: number;
  ChainName: string;
  ChainId: string;
  CreateTime: number;
  OrgNum: number;
  NodeNum: number;
  Status: 0 | 1 | 2 | 3; // 链状态 0：已启动 1：未启动 2失效 3 暂停
  Monitor: 0 | 1; // 链状态 1：已启动 0：未启动
  AutoReport: number;
  ChainMode: string; // 链证书模式 permissionedWithCert 证书模式 public 公钥模式
}
export interface StakeItem {
  NodeName: string;
  RemarkName: string;
  Count?: number;
}

export type StakeItemKeys = keyof StakeItem;

export interface ChainCreateRequest {
  ChainId: string;
  ChainName: string;
  BlockTxCapacity: number;
  /**
   * ms
   */
  BlockInterval: number;
  TxTimeout: number;
  ChainMode: number;
  /**
   * 共识算法 0:SOLO; 1:TBFT; 4:RAFT; 3:HOTSTUFF
   */
  Consensus: number;
  Algorithm?: string;
  Nodes: {
    // 节点所属组织id
    OrgId: string;
    NodeList: {
      NodeName: string;
      NodeIp: string;
      NodeRpcPort: number;
      NodeP2pPort: number;
    }[];
  }[];
  CommonNodes?: {
    // 节点所属组织id
    OrgId: string;
    NodeList: {
      NodeName: string;
      NodeIp: string;
      NodeRpcPort: number;
      NodeP2pPort: number;
    }[];
  }[];
  Monitor: 0 | 1;
  ChainmakerImprove: 0 | 1;

  /**
   * 是否开启tls， 0：开启 1：不开启
   */
  Tls?: 0 | 1;

  /**
   * 0：不开启，1：开启
   */
  DockerVm: 0 | 1;
  // 0:是; 1:否
  Single: 0 | 1;
  Admins?: string[];
  StakeMinCount?: number;
  Stakes?: StakeItem[];
  /**
   * 是否开启http， 1：开启 0：不开启
   */
  EnableHttp?: 0 | 1;
}

export type ChainDeleteRequest = Pick<Chain, 'ChainId'>;
export interface ReSubChainRequest {
  ChainId: string;
}

export interface ChainSubscribeRequest {
  ChainId: string;
  OrgId: string;
  NodeRpcAddress: string;
  UserName?: string;
  AdminName?: string;
  Tls?: 0 | 1;
  TLSHostName?: string;
}

export type CertUser = { UserName: string };

export interface ChainGeneral {
  TxNum: number;
  BlockHeight: number;
  NodeNum: number;
  OrgNum: number;
  ContractNum: number;
}

export interface ChainDetail {
  Id: number;
  ChainId: string;
  ChainName: string;
  Version: string;
  Sequence: string;
  BlockTxCapacity: number;
  TxTimeout: number;
  BlockInterval: number;
  Reason: string;
  DockerVm: 0 | 1;
  ChainMode: string; // 账户模式
  Consensus: number; // 共识算法 0:SOLO; 1:TBFT; 3:MaxBFT 4:RAFT 5：DPOS
  NodeRpcHost: string; // 节点的RPC地址
  Tls: 0 | 1; // 是否开启TLS
  Protocol: string; // 链通讯方式，是HTTP还是GRPC
  TlsHostname: string; // TLShostname
}

export interface ChainSubscribeConfig {
  ChainMode: ChainModes;
  ChainId: string;
  Tls: ChainCreateRequest['Tls'];
  Org: {
    OrgId: string;
    OrgName: string;
    // pwc模式下管理员
    UserName: string[];
    NodeRpcAddress: string[];
    // pk模式下管理员
    AdminName: string[];
  }[];
}

export interface ChainReConfigRequest {
  ChainId: string;
  BlockTxCapacity: number;
  TxTimeout: number;
  BlockInterval: number;
  Reason?: string;
}

export interface ChainAuthRequest {
  Type: number;
  Rule: number; // 自定义=9
  ChainId: string;
  PercentNum?: number;
  OrgList: {
    OrgId: string;
  }[];
  RoleList: {
    Role: number;
  }[];
  AuthName?: string; // 权限名称
  Reason?: string; // 修改原因
}

/**
 * 获取区块链浏览器中区块列表、交易列表、合约列表参数定义
 */
export interface IChainBrowserTableRequest extends PageQuery {
  ChainId: string;
  BlockHash?: string;
  BlockHeight?: number;
  TxId?: string;
  ContractName?: string;
}

export interface IChainBrowserBlockItem {
  Id: number;
  BlockHeight: number;
  NodeName: string;
  BlockHash: string;
  TxNum: number;
  Timestamp: number;
}

export interface IChainBrowserTxItem {
  Id: number;
  BlockHeight: number;
  TxId: string;
  OrgName: string;
  UserName: string;
  ContractName: string;
  ContractMethod: string;
  ContractParameters: string;
  Timestamp: number;
  Addr: string;
}

export interface IChainBrowserContractItem {
  Id: number;
  ContractName: string;
  ContractVersion: string;
  ContractOperator: string;
  TxNum: number;
  Timestamp: number;
  Addr?: string;
}

export interface IChainBrowserBlockDetailRequest {
  ChainId: string;
  Id: number;
}

export interface IChainBrowserBlockDetail {
  Id: number;
  BlockHeight: number;
  BlockHash: string;
  PreBlockHash: string;
  RwSetHash: string;
  TxRootHash: string;
  DagHash: string;
  OrgName: string;
  NodeName: string;
  Timestamp: number;
}

export interface IChainBrowserTxDetailRequest {
  ChainId: string;
  Id?: number;
  TxId?: string;
}

export interface IContractParameter {
  key: string;
  value: string;
  fullData?: string;
}

export interface IChainBrowserTxDetail {
  Id: number;
  BlockHeight: number;
  BlockHash: string;
  TxStatusCode: string;
  TxType: string;
  TxId: string;
  OrgName: string;
  UserName: string;
  Gas: string;
  ContractName: string;
  ContractMethod: string;
  Timestamp: number;
  ContractParameters: IContractParameter[];
  ContractResult: string;
  OrgList: string[] | null;
  Addr: string;
}

export interface IChainBrowserContractDetailRequest {
  ChainId: string;
  Id: number;
}

export interface IChainBrowserContractDetail {
  Id: number;
  ContractName: string;
  Creator: string;
  TxId: string;
  CreateTime: number;
  Addr?: string;
}

export interface IChainContractDetail {
  Id: number;
  ContractName: string;
  ContractVersion: string;
  ContractStatus: ContractManage['Status'];
  RuntimeType: number;
  /**
   * 反序列化后结果
   * @see InvokeRecordRequest['Parameters']
   */
  Parameters: string;
  /**
   * 反序列化后结果
   * @see ChainContractMethodsDecoded
   */
  Methods: string;
  AbiName: string;
  EvmAbiSaveKey: string;
  Reason: string;
}

export type ChainContractMethodsDecoded = {
  MethodName: string;
  MethodKey: string;
  MethodFunc?: 'query' | 'invoke';
}[];

export interface IChainNodeListRequest extends PageQuery {
  ChainId: string;
  NodeName?: string;
}

export const ChainNodeTypeDescMap = {
  0: '共识节点',
  1: '同步节点',
};

export interface IChainNodeItem {
  Id: number;
  OrgName: string;
  NodeName: string;
  /**
   * 节点类型
   */
  NodeType: keyof typeof ChainNodeTypeDescMap;
  NodeId: string;
  NodeAddr: string;
  NodePort: string;
  UpdateType: string;
  OrgNodeId: number;
}

export interface IChainNodeDetailRequest {
  ChainId: string;
  NodeId: number;
  OrgNodeId: number;
}

export interface LinkNodeList {
  LinkNodeName: string;
  LinkNodeType: 0 | 1;
}

export interface IChainNodeDetail {
  OrgName: string;
  NodeName: string;
  NodeType: IChainNodeItem['NodeType'];
  NodeId: string;
  NodeAddr: string;
  NodePort: string;
  UpdateType: string;
  CreateTime: number;
  LinkNodeList: LinkNodeList[];
}

export interface IChainOrgListRequest extends PageQuery {
  ChainId: string;
  OrgName?: string;
}

export interface IChainOrgItem {
  Id: number;
  OrgName: string;
  OrgId: string;
  NodeNum: number;
  CreateTime: number;
}

export interface AuthOrgRequest {
  ChainId: string;
  Type: number;
  AuthName: string;
}

export interface AuthOrg extends CertOrg {
  /**
   * 1为选中
   */
  Selected: 0 | 1;
}

export interface AuthRole {
  Role: keyof typeof AuthRoleMap;
  Selected: 0 | 1;
}

export type ContractManageListRequest = {
  ChainId: string;
  ContractName?: string;
  VoteStatus?: number;
  Status?: number;
} & PageQuery;

export const ContractStatusEnum: {
  [index: string]: {
    value: number;
    text: string;
  };
} = {
  ContractInitStored: { value: 0, text: '新建合约已存储' },
  ContractUpgradeStored: { value: 1, text: '升级合约已存储' },
  ContractInitFailure: { value: 2, text: '合约初始化部署失败' },
  ContractInitOk: { value: 3, text: '合约初始化部署成功' },
  ContractUpgradeFailure: { value: 4, text: '合约升级部署失败' },
  ContractUpgradeOK: { value: 5, text: '合约升级部署成功' },
  ContractFreezeFailure: { value: 6, text: '合约冻结失败' },
  ContractFreezeOK: { value: 7, text: '合约冻结成功' },
  ContractUnfreezeFailure: { value: 8, text: '合约解冻失败' },
  ContractUnfreezeOK: { value: 9, text: '合约解冻成功' },
  ContractRevokeFailure: { value: 10, text: '合约注销失败' },
  ContractRevokeOK: { value: 11, text: '合约注销成功' },
} as const;

export interface ContractManage {
  Id: number;
  OrgName: string;
  UserName: string;
  ContractName: string;
  /**
   * @see ContractStatusEnum
   */
  Status: number;
  VoteStatus: VoteManage['VoteStatus'];
  Version: string;
  CreateTime: number;
  RuntimeType: number;
}

export type ContractForInvoke = Pick<ContractManage, 'ContractName'> & {
  ContractId: number;
};

export interface ContractRuntimeType {
  RuntimeTypeName: string;
  RuntimeTypeType: number;
}

export interface ContractInstallRequest {
  ChainId: string;
  ContractName: string;
  ContractVersion: string;
  CompileSaveKey: string;
  EvmAbiSaveKey?: string;
  RuntimeType: number;
  Parameters: { Key: string; Value: string }[];
  Methods: ChainContractMethodsDecoded;
  Reason?: string;
}

export type ContractUpgradeRequest = Pick<
  ContractInstallRequest,
  'ChainId' | 'RuntimeType' | 'ContractName' | 'Parameters'
> & {
  ContractVersion: string;
  Reason?: string;
};

export interface ContractDeleteRequest {
  ChainId: string;
  ContractName: string;
}
/**
 * 销毁合约/冻结合约/解冻合约
 */
export interface ContractFreezeRequest {
  ChainId: string;
  ContractName: string;
  Reason: string;
}

export interface InvokeRecord {
  Id: number;
  TxId: string;
  OrgName: string;
  UserName: string;
  ContractName: string;
  Status: 0 | 1 | 2;
  CreateTime: number;
  TxStatus: 0 | 1;
}

export interface InvokeRecordListRequest extends PageQuery {
  ChainId: string;
  TxId?: string;
  Status: TableFilterField<InvokeRecord['Status']>;
  TxStatus: TableFilterField<InvokeRecord['TxStatus']>;
}

export interface InvokeRecordRequest {
  ChainId: string;
  ContractName: string;
  MethodName: string;
  MethodFunc: 'query' | 'invoke';
  Parameters?: { Key: string; Value: string }[];
}

export interface VoteManage {
  Id: number;
  StartOrgName: string;
  VoteType: number;
  PolicyType: number;
  PassPercent: string;
  // 1表示已投票
  VoteResult: 0 | 1;
  // 1描述已投票，0表示投票中
  VoteStatus: 0 | 1;
  CreateTime: number;
  Reason: string;
  VoteDetail: string;
}

export interface VotManageListRequest extends PageQuery {
  ChainId: string;
  OrgId?: string;
  VoteStatus?: VoteManage['VoteStatus'];
  VoteType?: number;
  ChainMode: string; // 链证书模式 permissionedWithCert 证书模式 public 公钥模式
  AdminName?: string; // 管理员名称
}

export interface VoteDetail {
  Id: number;
  StartOrgName: string;
  VoteType: number;
  PolicyType: number;
  Reason: string;
  VoteDetail: string;
  VoteStatus: VoteManage['VoteStatus'];
  PassOrgs: string[] | null;
  PassPercent: string;
  UnVotedOrgs: string[] | null;
  UnVotedPercent: string;
}

export interface VoteRequest {
  VoteId: number;
  /**
   * 1:同意; 2:反对
   */
  VoteResult: 1 | 2;
}

export interface IHomePageSearchRequest {
  KeyWord: string;
  ChainId: string;
}

export interface IHomePageSearch {
  Id: number;
  Type: 0 | 1 | 2 | 3;
}

export interface ChainAuth {
  Type: number;
  /**
   * 投票规则
   */
  PolicyType: number;
  /**
   * @deprecated 删除
   */
  PercentNum?: string;
  AuthName: string; // 自定义权限名称
  OrgType: number; // 是否全选 1 是全选  0 是 不全选
}

export interface ChainMode {
  /**
   * 证书模式/公钥模式
   */
  ChainModeName: string;
  /**
   * 链证书模式 permissionedWithCert 证书模式 public 公钥模式
   */
  ChainMode: string;
}

export interface GetCertUserListParam {
  OrgId?: string;
  ChainMode: ChainModes;
  Algorithm?: number;
}

export interface GetAdminResData {
  AdminName: string;
  Addr: string;
}
